package yxy.game.pm2.module.tower;

import org.joda.time.DateTime;
import org.redisson.api.RMap;

import yxy.apple.util.redisson.RedisException;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.module.AreaModule;
import yxy.game.pm2.module.battle.BattleModule;
import yxy.game.pm2.module.battle.BattleRecord;

public class TowerFloorModule extends AreaModule {
	// bean===========================================================================
	private int floor;
	private TowerFloorRecord bestRound;// 最少回合
	private TowerFloorRecord bestPower;// 最小战力

	public int getFloor() {
		return floor;
	}

	public void setFloor(int floor) {
		this.floor = floor;
	}

	public TowerFloorRecord getBestRound() {
		return bestRound;
	}

	public void setBestRound(TowerFloorRecord bestRound) {
		this.bestRound = bestRound;
	}

	public TowerFloorRecord getBestPower() {
		return bestPower;
	}

	public void setBestPower(TowerFloorRecord bestPower) {
		this.bestPower = bestPower;
	}

	// func===========================================================================

	public void record(String playerCode, BattleModule module) {
		try {
			if (tryLock()) {
				recordBestRound(playerCode, module);
				recordBestPower(playerCode, module);
			}
		} catch (Exception e) {
		} finally {
			unlock();
		}
	}

	private void recordBestRound(String playerCode, BattleModule module) {
		long round = module.getRound();
		TowerFloorRecord record = getBestRound();
		if (record == null) {
//			String recordCode = BattleRecord.randomCode();
			String recordCode = String.format("towerBestRoundFloor%s:%s", getFloor(), module.getPlayerCode());
			BattleRecord battleRecord = module.saveRecord(recordCode);
			record = new TowerFloorRecord();
			record.setPlayerCode(playerCode);
			record.setDate(DateTime.now());
			record.setValue(round);
			record.setRecordCode(battleRecord.getCode());
			setBestRound(record);
			set();
			return;
		}
		if (record.getValue() < round) {
			return;
		}
		String recordCode = record.getRecordCode();
		module.saveRecord(recordCode);
		record.setPlayerCode(playerCode);
		record.setValue(round);
		record.setDate(DateTime.now());
		set();
	}

	private void recordBestPower(String playerCode, BattleModule module) {
		long power = module.getTeamA().getPower();
		TowerFloorRecord record = getBestPower();
		if (record == null) {
//			String recordCode = BattleRecord.randomCode();
			String recordCode = String.format("towerBestPowerFloor%s:%s", getFloor(), module.getPlayerCode());
			BattleRecord battleRecord = module.saveRecord(recordCode);
			record = new TowerFloorRecord();
			record.setPlayerCode(playerCode);
			record.setDate(DateTime.now());
			record.setValue(power);
			record.setRecordCode(battleRecord.getCode());
			setBestPower(record);
			set();
			return;
		}
		if (record.getValue() < power) {
			return;
		}
		String recordCode = record.getRecordCode();
		module.saveRecord(recordCode);
		record.setPlayerCode(playerCode);
		record.setValue(power);
		record.setDate(DateTime.now());
		set();
	}

	// redis==========================================================================

	static public String key(int areaId) {
		return key(areaId, "TOWERFLOOR");
	}

	static private RMap<Integer, TowerFloorModule> touchMap(int areaId) throws RedisException {
		return RedisManager.client(redis()).getMap(key(areaId));
	}

	public void set() {
		try {
			RMap<Integer, TowerFloorModule> map = touchMap(getAreaId());
			map.put(getFloor(), this);
		} catch (RedisException e) {
		}
	}

	static public TowerFloorModule get(int areaId, int floor) {
		try {
			RMap<Integer, TowerFloorModule> map = touchMap(areaId);
			if (!map.containsKey(floor)) {
				TowerFloorModule module = create(areaId, floor);
				map.put(floor, module);
			}
			return map.get(floor);
		} catch (RedisException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static TowerFloorModule create(int areaId, int floor) {
		TowerFloorModule module = new TowerFloorModule();
		module.setFloor(floor);
		module.setAreaId(areaId);
		return module;
	}

	public static TowerFloorModule get(String playerCode, int floor) {
		try {
			AreaBean area = area(playerCode);
			return TowerFloorModule.get(area.getAreaId(), floor);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// lock==========================================================================

	@Override
	public String lockKey() {
		return String.format("lock:%s", key(getAreaId()));
	}
}
